package it.uniroma2.imagetranscoder;


import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.util.UUID;


public class NioTransferCopy {

	
	private String resource;
	
	public NioTransferCopy (String sourceParentDirectory){
		resource = sourceParentDirectory;		 
	}
	
	public File inputstreamToFile(InputStream is){
		
		 OutputStream outputStream= null;
		 File file = new File (resource+File.separator+"fileIn_"+UUID.randomUUID().toString()+"_"+System.currentTimeMillis()+".tmp");
		 
		try {
			outputStream = new FileOutputStream(file);
		

		int read = 0;
		byte[] bytes = new byte[1024];

		while ((read = is.read(bytes)) != -1) {
			outputStream.write(bytes, 0, read);
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			try{
			outputStream.close();
			is.close();
			} catch (Exception e){
				
			}
		}
		return file;
		  
	}

	 public  void nioTransferCopy(File source, File target) {
	
		 
		 	FileChannel in = null;
	        FileChannel out = null;
	        
	        
	        FileInputStream inStream = null;
	        FileOutputStream outStream = null;

	        try {
	            inStream = new FileInputStream(source);
	            outStream = new FileOutputStream(target);

	            in = inStream.getChannel();
	            out = outStream.getChannel();

	            in.transferTo(0, in.size(), out);
	        } catch (IOException e) {
	            e.printStackTrace();
	        } finally {
	            close(inStream);
	            close(in);
	            close(outStream);
	            close(out);
	        }
	    }

	    private static void close(Closeable closable) {
	        if (closable != null) {
	            try {
	                closable.close();
	            } catch (IOException e) {
	                e.printStackTrace();
	            }
	        }
	    }
	
	private void runBenchmark(String filename){
		 System.out.print("Start benchmark with " +filename + " file ");	        
	        File fileIn = new File(this.resource+File.separator+filename);
	        long size = fileIn.length()/1024;
	        String dim = size+ " KB";
	        if (size > 1024) {
	        	size/=1024L;
	        	dim = size + " MB";
	        }
	        if (size >= 1024) {
	        	size/=1024L;
	        	dim = size + " GB";
	        	
	        }
	        
	        System.out.println("("+ dim +")");
	        File fileOut = new File(this.resource+File.separator+"tmp"+File.separator+filename);
	        fileOut.getParentFile().mkdirs();
	        long start = System.currentTimeMillis();
	        try {
				InputStream is = new FileInputStream(fileIn);
				this.nioTransferCopy(this.inputstreamToFile(is), fileOut);
				long end = System.currentTimeMillis();
				System.out.println(filename + "'s time: " + (end-start));
				System.out.println(filename +" "+ (fileOut.delete()?"deleted":"not deleting"));
	        } catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
	/**
	 * @param args
	 */
	
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		NioTransferCopy nioTransferCopy = new NioTransferCopy();
//        try {
//		
//		 BufferedOutputStream console = null;
//	        try {
//	            console = new BufferedOutputStream(new FileOutputStream("console.log"));
//
//	            System.setOut(new PrintStream(console));
//	        } catch (FileNotFoundException e) {
//	            e.printStackTrace();
//	        }
	       
        	

        
//        	
//			nioTransferCopy.runBenchmark("little-binary");
//			nioTransferCopy.runBenchmark("middle-binary");
//			nioTransferCopy.runBenchmark("big-binary");
//			nioTransferCopy.runBenchmark("fat-binary");
//			nioTransferCopy.runBenchmark("super-binary");
//			
//			
//	 
////	        
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
	}

}
